home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / EXPLODE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  9.6 KB  |  389 lines

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6.  
  7. #ifndef __sgi
  8. /* Most math.h's do not define float versions of the trig functions. */
  9. #define sinf sin
  10. #define cosf cos
  11. #define atan2f atan2
  12. #endif
  13.  
  14. /* Some <math.h> files do not define M_PI... */
  15. #ifndef M_PI
  16. #define M_PI 3.14159265358979323846
  17. #endif
  18.  
  19. static int texture = 1;
  20. static float rot = 0;
  21. static float opacity = 1.0;
  22. static float intensity = 1.0;
  23. static float size = .001, delta = 0;
  24. static float scale = 1.;
  25. static float transx, transy, rotx, roty;
  26. static int ox = -1, oy = -1;
  27. static int mot = 0;
  28. #define PAN    1
  29. #define ROT    2
  30.  
  31. void
  32. pan(int x, int y) {
  33.     transx +=  (x-ox)/500.;
  34.     transy -= (y-oy)/500.;
  35.     ox = x; oy = y;
  36.     glutPostRedisplay();
  37. }
  38.  
  39. void
  40. rotate(int x, int y) {
  41.     rotx += x-ox;
  42.     if (rotx > 360.) rotx -= 360.;
  43.     else if (rotx < -360.) rotx += 360.;
  44.     roty += y-oy;
  45.     if (roty > 360.) roty -= 360.;
  46.     else if (roty < -360.) roty += 360.;
  47.     ox = x; oy = y;
  48.     glutPostRedisplay();
  49. }
  50.  
  51. void
  52. motion(int x, int y) {
  53.     if (mot == PAN) pan(x, y);
  54.     else if (mot == ROT) rotate(x,y);
  55. }
  56.  
  57. void
  58. mouse(int button, int state, int x, int y) {
  59.     if(state == GLUT_DOWN) {
  60.     switch(button) {
  61.     case GLUT_LEFT_BUTTON:
  62.         mot = PAN;
  63.         motion(ox = x, oy = y);
  64.         break;
  65.     case GLUT_RIGHT_BUTTON:
  66.         mot = ROT;
  67.         motion(ox = x, oy = y);
  68.         break;
  69.     case GLUT_MIDDLE_BUTTON:
  70.         break;
  71.     }
  72.     } else if (state == GLUT_UP) {
  73.     mot = 0;
  74.     }
  75. }
  76.  
  77. void afunc(void) {
  78.     static int state;
  79.     if (state ^= 1) {
  80.     glAlphaFunc(GL_GREATER, .01);
  81.     glEnable(GL_ALPHA_TEST);
  82.     } else {
  83.     glDisable(GL_ALPHA_TEST);
  84.     }
  85. }
  86.  
  87. void bfunc(void) {
  88.     static int state;
  89.     if (state ^= 1) {
  90.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  91.     glEnable(GL_BLEND);
  92.     } else {
  93.     glDisable(GL_BLEND);
  94.     }
  95. }
  96.  
  97. void tfunc(void) {
  98.     texture ^= 1;
  99. }
  100.  
  101. void up(void) { scale += .1; }
  102. void down(void) { scale -= .1; }
  103. void left(void) { intensity -= .05f; if (intensity < 0.f) intensity = 0.0f; }
  104. void right(void) { intensity += .05f; if (intensity > 1.f) intensity = 1.0f; }
  105.  
  106. void help(void) {
  107.     printf("Usage: explode [image]\n");
  108.     printf("'h'            - help\n");
  109.     printf("'a'            - toggle alpha test\n");
  110.     printf("'b'            - toggle blend\n");
  111.     printf("'t'            - toggle texturing\n");
  112.     printf("'UP'           - scale up\n");
  113.     printf("'DOWN'         - scale down\n");
  114.     printf("'LEFT'       - darken\n");
  115.     printf("'RIGHT'       - brighten\n");
  116.     printf("left mouse     - pan\n");
  117.     printf("right mouse    - rotate\n");
  118. }
  119.  
  120. void init(char *filename) {
  121.     static unsigned *image;
  122.     static int width, height, components;
  123.     if (filename) {
  124.     image = read_texture(filename, &width, &height, &components);
  125.     if (image == NULL) {
  126.         fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  127.             filename);
  128.         exit(EXIT_FAILURE);
  129.     } else {
  130.         printf("%d x %d image loaded\n", width, height);
  131.     }
  132.     if (components != 2 && components != 4) {
  133.         printf("must be an RGBA or LA image\n");
  134.         exit(EXIT_FAILURE);
  135.     }
  136.     } else {
  137.     int i, j;
  138.     unsigned char *img;
  139.     components = 4; width = height = 512;
  140.     image = (unsigned *) malloc(width*height*sizeof(unsigned));
  141.     img = (unsigned char *)image;
  142.     for (j = 0; j < height; j++)
  143.         for (i = 0; i < width; i++) {
  144.         int w2 = width/2, h2 = height/2;
  145.         if (i & 32)
  146.             img[4*(i+j*width)+0] = 0xff;
  147.         else
  148.             img[4*(i+j*width)+1] = 0xff;
  149.         if (j&32)
  150.             img[4*(i+j*width)+2] = 0xff;
  151.         if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 &&
  152.             (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff;
  153.         }
  154.  
  155.     }
  156.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  157.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  158.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  159.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  160.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  161.                  height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  162.                  image);
  163.     glEnable(GL_TEXTURE_2D);
  164.     glMatrixMode(GL_PROJECTION);
  165.     glLoadIdentity();
  166.     gluPerspective(50.,1.,.1,20.);
  167.     glMatrixMode(GL_MODELVIEW);
  168.     glLoadIdentity();
  169.     glTranslatef(0.,0.,-5.5);
  170.     glClearColor(.25f, .25f, .75f, .25f);
  171.  
  172.     glAlphaFunc(GL_GREATER, 0.016);
  173.     glEnable(GL_ALPHA_TEST);
  174.  
  175.     glEnable(GL_BLEND);
  176.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  177.     glEnable(GL_DEPTH_TEST);
  178.  
  179.     glEnable(GL_LIGHT0);
  180.     glEnable(GL_COLOR_MATERIAL);
  181.     glEnable(GL_NORMALIZE);
  182. }
  183.  
  184. void
  185. animate(void) {
  186.     if (delta > 10) {
  187.     delta = 0.f;
  188.     size = 0.f;
  189.         opacity = 1.f;
  190.     rot = 0.f;
  191.     }
  192.     size += .08f;
  193.     delta += .07f;
  194.     rot += .9f;
  195.     opacity -= .005f;
  196.  
  197.     glutPostRedisplay();
  198. }
  199.  
  200. void
  201. cube(void) {
  202.     glBegin(GL_QUADS);
  203.     glNormal3f(0.f, 0.f, -1.f);
  204.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
  205.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
  206.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
  207.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
  208.  
  209.     glNormal3f(0.f, 0.f, 1.f);
  210.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
  211.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
  212.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
  213.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
  214.  
  215.     glNormal3f(0.f, 1.f, 0.f);
  216.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0, -1.0);
  217.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0, -1.0);
  218.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
  219.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
  220.  
  221.     glNormal3f(0.f, -1.f, 0.f);
  222.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
  223.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
  224.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0,  1.0);
  225.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0,  1.0);
  226.  
  227.     glNormal3f( 1.f, 0.f, 0.f);
  228.     glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
  229.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0, -1.0);
  230.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
  231.     glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0,  1.0);
  232.  
  233.     glNormal3f(-1.f, 0.f, 0.f);
  234.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
  235.     glTexCoord2f(1.0, 0.0); glVertex3f(-1.0,  1.0, -1.0);
  236.     glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
  237.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0,  1.0);
  238.     glEnd();
  239. }
  240.  
  241. static void calcMatrix(void);
  242.  
  243. void display(void) {
  244.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  245.  
  246.     glLoadIdentity();
  247. #define RAD(x) (((x)*M_PI)/180.)
  248.     gluLookAt(-sinf(RAD(rotx))*5.5,transy,cosf(RAD(rotx))*5.5, 0.,0.,0., 0.,1.,0.);
  249.  
  250.     /* floor */
  251.     glColor4f(0.f,.2f,0.f,1.f);
  252.     glBegin(GL_POLYGON);
  253.     glVertex3f(-4.0, -1.0, -4.0);
  254.     glVertex3f( 4.0, -1.0, -4.0);
  255.     glVertex3f( 4.0, -1.0,  4.0);
  256.     glVertex3f(-4.0, -1.0,  4.0);
  257.     glEnd();
  258.  
  259.     glEnable(GL_LIGHTING);
  260.     glPushMatrix();
  261.     glColor3f(.3f,.3f,.3f);
  262.     glPushMatrix();
  263.     glTranslatef(-1.f, -1.+.2f, -1.5f);
  264.     glScalef(.2f,.2f, .2f);
  265.     cube();
  266.     glPopMatrix();
  267.     glDisable(GL_LIGHTING);
  268.  
  269.     glTranslatef(-1.f, -1.f, -1.5f);
  270.     calcMatrix();
  271.     glScalef(size,size,1.);
  272.     if (texture) glEnable(GL_TEXTURE_2D);
  273.     glColor4f(intensity, intensity, intensity, opacity);
  274.     glDepthMask(0);
  275.     glBegin(GL_POLYGON);
  276.     glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
  277.     glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
  278.     glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
  279.     glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
  280.     glEnd();
  281.     glDepthMask(1);
  282.     glPopMatrix();
  283.     glDisable(GL_TEXTURE_2D);
  284.  
  285.     glutSwapBuffers();
  286. }
  287.  
  288. void reshape(int w, int h) {
  289.     glViewport(0, 0, w, h);
  290. }
  291.  
  292. /* ARGSUSED1 */
  293. void
  294. key(unsigned char key, int x, int y) {
  295.     switch(key) {
  296.     case 'a': afunc(); break;
  297.     case 'b': bfunc(); break;
  298.     case 'h': help(); break;
  299.     case 't': tfunc(); break;
  300.     case '\033': exit(EXIT_SUCCESS); break;
  301.     default: break;
  302.     }
  303.     glutPostRedisplay();
  304. }
  305.  
  306. /* ARGSUSED1 */
  307. void
  308. special(int key, int x, int y) {
  309.     switch(key) {
  310.     case GLUT_KEY_UP:    up(); break;
  311.     case GLUT_KEY_DOWN:    down(); break;
  312.     case GLUT_KEY_LEFT:    left(); break;
  313.     case GLUT_KEY_RIGHT:right(); break;
  314.     }
  315. }
  316.  
  317. int main(int argc, char** argv) {
  318.     glutInitWindowSize(512, 512);
  319.     glutInit(&argc, argv);
  320.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  321.     (void)glutCreateWindow(argv[0]);
  322.     init(argc == 1 ? "data/smoke.la" : argv[1]);
  323.     glutDisplayFunc(display);
  324.     glutKeyboardFunc(key);
  325.     glutSpecialFunc(special);
  326.     glutReshapeFunc(reshape);
  327.     glutMouseFunc(mouse);
  328.     glutMotionFunc(motion);
  329.     glutIdleFunc(animate);
  330.     glutMainLoop();
  331.     return 0;
  332. }
  333.  
  334. void
  335. printmat(float *m) {
  336.     int i;
  337.     for(i = 0; i < 4; i++) {
  338.     printf("%f %f %f %f\n", m[4*i+0], m[4*i+1], m[4*i+2], m[4*i+3]);
  339.     }
  340. }
  341.  
  342. void
  343. buildRot(float theta, float x, float y, float z, float m[16]) {
  344.     float d = x*x + y*y + z*z;
  345.     float ct = cosf(RAD(theta)), st = sinf(RAD(theta));
  346.  
  347.     /* normalize */
  348.     if (d > 0) {
  349.     d = 1/d;
  350.     x *= d;
  351.     y *= d;
  352.     z *= d;
  353.     }
  354.  
  355.     m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0;
  356.     m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0;
  357.     m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0;
  358.     m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
  359.  
  360.     /* R = uu' + cos(theta)*(I-uu') + sin(theta)*S
  361.      *
  362.      * S =  0  -z   y    u' = (x, y, z)
  363.      *        z   0  -x
  364.      *       -y   x   0
  365.      */
  366.  
  367.      m[0] = x*x + ct*(1-x*x) + st*0;
  368.      m[4] = x*y + ct*(0-x*y) + st*-z;
  369.      m[8] = x*z + ct*(0-x*z) + st*y;
  370.  
  371.      m[1] = y*x + ct*(0-y*x) + st*z;
  372.      m[5] = y*y + ct*(1-y*y) + st*0;
  373.      m[9] = y*z + ct*(0-y*z) + st*-x;
  374.  
  375.      m[2] = z*x + ct*(0-z*x) + st*-y;
  376.      m[6] = z*y + ct*(0-z*y) + st*x;
  377.      m[10]= z*z + ct*(1-z*z) + st*0;
  378. }
  379.  
  380. static void
  381. calcMatrix(void) {
  382.     float mat[16];
  383.  
  384.     glGetFloatv(GL_MODELVIEW_MATRIX, mat);
  385.  
  386.     buildRot(-180*atan2f(mat[8], mat[10])/M_PI, 0, 1, 0, mat);
  387.     glMultMatrixf(mat);
  388. }
  389.